﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace net.zxteam.ZXLexer
{
    internal class ProgramArgsParser
    {
        public static ProgramArgs Parse(string[] args) { return new ProgramArgsImpl(args); }

        private class ProgramArgsImpl : ProgramArgs
        {
            public ProgramArgsImpl(string[] args)
            {
                _args = (string[])args.Clone();
                _optionSet = new NDesk.Options.OptionSet() 
                {
                    { "a|annotationNamespace=", "Embedded annotation namespace (default net.zxteam.zxlang). Conflict with External schema.", v => this.AnnotationNamespace = v },
                    { "p|peg=", "External PEG file (). Conflict with External schema.", v => this.ExternalPegFile = v },
                    { "o|out=", "Output file", v => this.OutputFile = v },
                    { "h|help", "Show help", v => this.Help = true }
                };

                if (_args.Length == 0)
                {
                    this.Help = true;
                    return;
                }

                ApplyDefaultValues();

                try
                {
                    List<string> extra = _optionSet.Parse(args);
                    if (extra == null || extra.Count == 0)
                    {
                        Help = true;
                    }
                    else
                    {
                        this.InputFiles = extra.ToArray();
                    }
                }
                catch(Exception ex)
                {
                    Help = true;
                    ParseException = ex;
                }
            }

            private void ApplyDefaultValues()
            {
                this.AnnotationNamespace = "net.zxteam.zxlang";
            }

            public Exception ParseException { get; set; }

            public string AnnotationNamespace { get; set; }
            public string ExternalPegFile { get; set; }
            public IEnumerable<string> InputFiles { get; set; }
            public string OutputFile { get; set; }
            public bool Help { get; set; }

            public void ShowHelp(System.IO.TextWriter to)
            {
                Console.WriteLine("Usage:");
                Console.WriteLine("\tLexer.exe [OPTIONS]");
                Console.WriteLine();
                Console.WriteLine("Options:");
                _optionSet.WriteOptionDescriptions(to);
            }

            private readonly NDesk.Options.OptionSet _optionSet;
            private readonly string[] _args;
        }
    }
}
